package com.twetec.cms.adapter.pc.backend.controller.website;

import cn.hutool.core.util.ZipUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.twetec.cms.adapter.pc.backend.constant.RabbitMQConstants;
import com.twetec.cms.adapter.pc.backend.response.R;
import com.twetec.cms.common.constant.StaticHtmlStatusEnum;
import com.twetec.cms.common.constant.StaticHtmlTypeEnum;
import com.twetec.cms.common.util.validate.ValidateUtil;
import com.twetec.cms.model.po.system.StaticLogPO;
import com.twetec.cms.model.po.user.UserPO;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.twetec.cms.model.po.website.MessageConvert;
import com.twetec.cms.model.po.website.ServerConvert;
import com.twetec.cms.model.po.website.SiteDeployServerPO;
import com.twetec.cms.model.vo.ucenter.UserVO;
import com.twetec.cms.model.vo.website.SiteDeployServerPageListVO;
import com.twetec.cms.model.vo.website.SiteDeployServerVO;
import com.twetec.cms.service.file.FastdfsFileService;
import com.twetec.cms.service.system.SiteDeployServerService;
import com.twetec.cms.service.system.StaticLogService;
import com.twetec.cms.service.ucenter.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: zhaichangzheng
 * @Date: 2022/3/1 11:43 （日期和时间）
 */

@Api(tags = "站点集群")
@RestController
@RequestMapping("/website/site-deploy-server")
public class SiteDeployServerController {

    @Autowired
    private SiteDeployServerService siteDeployServerService;

    @Value("${twetec.resource.storage-root-path}")
    private String rootPath;

    @Autowired
    private UserService userService;

    @Autowired
    private FastdfsFileService fastdfsFileService;

    @Autowired
    private StaticLogService staticLogService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @ApiOperation(value = "服务器分页查询列表", notes = "服务器分页查询列表")
    @GetMapping("/server-page-search-list")
    public R<SiteDeployServerPageListVO> serverPageSearchList( @ApiParam(value = "站点id", required = true, example = "123456789") @RequestParam(required = false) Long siteId,
                                                                @ApiParam(value = "服务器标识", required = false, example = "服务器1") @RequestParam(required = false) String serverIdentification,
                                                                @ApiParam(value = "状态 1表示启用 0表示禁用", required = false, example = "1") @RequestParam(required = false) Integer status,
                                                                @ApiParam(value = "访问页码", required = true, example = "1") @RequestParam(required = false) Integer page,
                                                                @ApiParam(value = "页面容量", required = true, example = "10") @RequestParam(required = false) Integer limit) {
        // 校验访问页码
        if (page == null || !ValidateUtil.Number(page) || page <= 0) { return R.failureRequestParam().msg("访问页码必填"); }
        // 校验访问数据条数
        if (limit == null || !ValidateUtil.Number(limit) || limit <= 0) { return R.failureRequestParam().msg("页面容量必填"); }
        // 检验站点id
        if (siteId == null || !ValidateUtil.Number(siteId)) return R.failureRequestParam().msg("站点id不能为空");

        QueryWrapper<SiteDeployServerPO> siteDeployServerPOQueryWrapper = new QueryWrapper<>();
        siteDeployServerPOQueryWrapper.lambda().eq(SiteDeployServerPO::getSiteId, siteId);
        if (null != serverIdentification) {
            siteDeployServerPOQueryWrapper.lambda().like(SiteDeployServerPO::getServerIdentification, serverIdentification);
        }

        if (null != status) {
            siteDeployServerPOQueryWrapper.lambda().eq(SiteDeployServerPO::getStatus, status);
        }

        Page<SiteDeployServerPO> pageList = siteDeployServerService.page(new Page<>(page, limit), siteDeployServerPOQueryWrapper);
        // 遍历records
        List<SiteDeployServerPO> records = pageList.getRecords();
        ArrayList<SiteDeployServerVO> siteDeployServerVOArrayList = new ArrayList<>();

        for (SiteDeployServerPO siteDeployServerPO : records) {
            SiteDeployServerVO siteDeployServerVO = new SiteDeployServerVO();
            BeanUtils.copyProperties(siteDeployServerPO, siteDeployServerVO);

            // 更新人姓名
            UserPO modifierUserPO = userService.getById(siteDeployServerPO.getModifierId());
            siteDeployServerVO.setModifierName(modifierUserPO.getName());

            // 添加到集合中
            siteDeployServerVOArrayList.add(siteDeployServerVO);
        }
        SiteDeployServerPageListVO siteClusterServerPageListVO = new SiteDeployServerPageListVO();
        siteClusterServerPageListVO.setList(siteDeployServerVOArrayList);
        siteClusterServerPageListVO.setPage(page);
        siteClusterServerPageListVO.setLimit(limit);
        siteClusterServerPageListVO.setTotal(pageList.getTotal());

        return R.success().data(siteClusterServerPageListVO);
    }


    @ApiOperation(value = "新增服务器", notes = "新增服务器")
    @PostMapping("/create-server")
    public R createServer(@ApiParam(value = "站点id", required = true, example = "123456789") @RequestParam(required = false) Long siteId,
                          @ApiParam(value = "服务器名称", required = true, example = "服务器1") @RequestParam(required = false) String serverIdentification,
                          @ApiParam(value = "部署路径", required = true, example = "11111111") @RequestParam(required = false) String route,
                          @ApiParam(value = "备注", required = false, example = "新增服务器的备注") @RequestParam(required = false) String remark,
                          @RequestAttribute("userId") Long userId) {
        // 校验服务器名称
        if (serverIdentification == null || StringUtils.isEmpty(serverIdentification)) { return R.failureRequestParam().msg("服务器名称必填"); }
        // 校验站点根目录
        if (route == null || StringUtils.isEmpty(route)) { return R.failureRequestParam().msg("部署路径必填"); }
        // 检验站点id
        if (siteId == null || !ValidateUtil.Number(siteId)) return R.failureRequestParam().msg("站点id不能为空");

        SiteDeployServerPO siteDeployServerPO = new SiteDeployServerPO();
        if (null != remark && !"".equals(remark)) {
            siteDeployServerPO.setRemark(remark);
        }
        siteDeployServerPO.setRoute(route);
        siteDeployServerPO.setServerIdentification(serverIdentification);
        siteDeployServerPO.setSiteId(siteId);
        siteDeployServerPO.setStatus(1);
        siteDeployServerPO.setCreatorId(userId);
        siteDeployServerPO.setModifierId(userId);
        boolean save = siteDeployServerService.save(siteDeployServerPO);

        if (!save) {
            return R.failure();
        }

        return  R.success();
    }

    @ApiOperation(value = "批量删除服务器", notes = "批量删除服务器")
    @DeleteMapping("/delete-server-by-ids")
    public R deleteServerByIds(@ApiParam(value = "ids(用英文逗号分隔)", required = true, example = "12312313123") @RequestParam(required = false) String ids,
                               @RequestAttribute("userId") Long userId) {
        // 检验id
        if (ids == null) return R.failureRequestParam().msg("ids不能为空");
        String[] split = ids.split(",");
        ArrayList<Long> idList = new ArrayList<>();
        for (String s : split) {
            idList.add(Long.parseLong(s));
        }

        UpdateWrapper<SiteDeployServerPO> siteDeployServerPOQueryWrapper = new UpdateWrapper<>();
        siteDeployServerPOQueryWrapper.set("MODIFIER_ID", userId);
        siteDeployServerPOQueryWrapper.set("is_deleted", 1);
        siteDeployServerPOQueryWrapper.in("ID", idList);
        boolean remove = siteDeployServerService.remove(siteDeployServerPOQueryWrapper);

        if (!remove) return R.failure();
        return  R.success();
    }

    @ApiOperation(value = "根据id更新服务器", notes = "根据id更新服务器")
    @PutMapping("/update-server-by-id")
    public R updateServerById(@ApiParam(value = "id", required = true, example = "123456789") @RequestParam(required = false) Long id,
                              @ApiParam(value = "站点id", required = true, example = "123456789") @RequestParam(required = false) Long siteId,
                              @ApiParam(value = "服务器名称", required = true, example = "服务器1") @RequestParam(required = false) String serverIdentification,
                              @ApiParam(value = "部署路径", required = true, example = "11111111") @RequestParam(required = false) String route,
                              @ApiParam(value = "备注", required = false, example = "新增服务器的备注") @RequestParam(required = false) String remark,
                              @RequestAttribute("userId") Long userId) {
        // 校验服务器名称
        if (serverIdentification == null || StringUtils.isEmpty(serverIdentification)) { return R.failureRequestParam().msg("服务器名称必填"); }
        // 校验站点根目录
        if (route == null || StringUtils.isEmpty(route)) { return R.failureRequestParam().msg("部署路径必填"); }
        // 检验站点id
        if (siteId == null || !ValidateUtil.Number(siteId)) return R.failureRequestParam().msg("站点id不能为空");
        // 检验id
        if (id == null || !ValidateUtil.Number(id)) return R.failureRequestParam().msg("id不能为空");

        SiteDeployServerPO siteDeployServerPO = new SiteDeployServerPO();
        if (null != remark && !"".equals(remark)) {
            siteDeployServerPO.setRemark(remark);
        }

        int length = route.length();
        if (route.charAt(length - 1) == '/') {
            route = route.substring(0, length - 1);
        }

        siteDeployServerPO.setRoute(route);
        siteDeployServerPO.setId(id);
        siteDeployServerPO.setServerIdentification(serverIdentification);
        siteDeployServerPO.setSiteId(siteId);
        siteDeployServerPO.setModifierId(userId);

        boolean update = siteDeployServerService.updateById(siteDeployServerPO);
        if (!update) return R.failure();

        return  R.success();
    }


    @ApiOperation(value = "更新服务器状态", notes = "更新服务器状态")
    @PutMapping("/update-server-status-by-id")
    public R updateServerStatusById(@ApiParam(value = "id", required = true, example = "12312313123") @RequestParam(required = false) Long id,
                                    @ApiParam(value = "状态 1表示启用 0表示禁用", required = true, example = "1") @RequestParam(required = false) Integer status,
                                    @RequestAttribute("userId") Long userId) {
        // 检验id
        if (id == null || !ValidateUtil.Number(id)) return R.failureRequestParam().msg("id不能为空");
        // 检验状态
        if (status == null || !ValidateUtil.Number(status)) return R.failureRequestParam().msg("status格式不正确");

        SiteDeployServerPO siteDeployServerPO = new SiteDeployServerPO();
        siteDeployServerPO.setStatus(status);
        siteDeployServerPO.setId(id);
        siteDeployServerPO.setModifierId(userId);

        boolean update = siteDeployServerService.updateById(siteDeployServerPO);
        if (!update) return R.failure();

        return  R.success();
    }

    @ApiOperation(value = "根据id删除服务器", notes = "根据id删除服务器")
    @DeleteMapping("/delete-server-by-id")
    public R deleteServerById(
            @ApiParam(value = "id", required = true, example = "12312313123") @RequestParam(required = false) Long id,
            @RequestAttribute("userId") Long userId) {
        // 检验id
        if (id == null || !ValidateUtil.Number(id)) return R.failureRequestParam().msg("id不能为空");
        UpdateWrapper<SiteDeployServerPO> siteDeployServerPOQueryWrapper = new UpdateWrapper<>();
        siteDeployServerPOQueryWrapper.set("MODIFIER_ID", userId);
        siteDeployServerPOQueryWrapper.set("is_deleted", 1);
        siteDeployServerPOQueryWrapper.eq("ID", id);

        boolean remove = siteDeployServerService.remove(siteDeployServerPOQueryWrapper);
        if (!remove) return R.failure();
        return  R.success();
    }

    @ApiOperation(value = "根据id获取服务器信息", notes = "根据id获取服务器信息")
    @GetMapping("/get-server-by-id")
    public R<SiteDeployServerVO> getServerById(
            @ApiParam(value = "id", required = true, example = "12312313123") @RequestParam(required = false) Long id) {

        // 校验id
        if (id == null || !ValidateUtil.Number(id)) { return R.failureRequestParam().msg("id输入有误"); }

        // 根据ID查询集群节点
        SiteDeployServerPO byId = siteDeployServerService.getById(id);
        if (byId == null) {
            return R.failure().msg("查询信息不存在");
        }

        // PO封装为VO
        SiteDeployServerVO siteClusterVO = new SiteDeployServerVO();
        BeanUtils.copyProperties(byId, siteClusterVO);

        return  R.success().data(siteClusterVO);
    }

    @ApiOperation(value = "部署", notes = "部署")
    @GetMapping("/deploy-server-by-site-id")
    public R deployServerBySiteId(
            @ApiParam(value = "站点id", required = true, example = "12312313123") @RequestParam(required = false) Long siteId,
            @RequestAttribute("userId") Long userId) {

        // 参数校验
        if (siteId == null || !ValidateUtil.Number(siteId) || siteId <= 0)
            return R.failureRequestParam().msg("站点id格式不正确");

        QueryWrapper<StaticLogPO> staticLogPOQueryWrapper = new QueryWrapper<>();
        staticLogPOQueryWrapper.eq("SITE_ID", siteId);
        staticLogPOQueryWrapper.eq("STATUS", StaticHtmlStatusEnum.JIN_XING_ZHONG.getValue());
        staticLogPOQueryWrapper.eq("STATIC_TYPE", StaticHtmlTypeEnum.ALL.getValue());
        StaticLogPO staticLogPO = staticLogService.getOne(staticLogPOQueryWrapper, false);
        if (null != staticLogPO && null != staticLogPO.getId()) {
            return R.failure().msg("静态化任务正在进行,请稍后再试!");
        }

        String sourcePath = rootPath + File.separator + siteId + File.separator + "html" + File.separator + "pc";
        String targetRoute = rootPath + File.separator + siteId + File.separator + "html" + File.separator + siteId + ".zip";
        File zip = ZipUtil.zip(sourcePath, targetRoute);
        String uploadZipURL = fastdfsFileService.uploadZip(zip);

        QueryWrapper<SiteDeployServerPO> siteDeployServerPOQueryWrapper = new QueryWrapper<>();
        siteDeployServerPOQueryWrapper.eq("SITE_ID", siteId);
        List<SiteDeployServerPO> list = siteDeployServerService.list(siteDeployServerPOQueryWrapper);
        if (null == list || list.size() == 0) {
            return R.failure().msg("部署配置未设置");
        }

        // 将配置信息转换为json
        ArrayList<ServerConvert> serverConverts = new ArrayList<>();
        for (SiteDeployServerPO siteDeployServerPO : list) {
            ServerConvert serverConvert = new ServerConvert();
            serverConvert.setServerId(siteDeployServerPO.getServerIdentification());
            serverConvert.setRoute(siteDeployServerPO.getRoute());
            serverConverts.add(serverConvert);
        }

        UserVO userVO = userService.getByUserId(userId);
        MessageConvert messageConvert = new MessageConvert();
        messageConvert.setStaticHtmlUrl(uploadZipURL);
        messageConvert.setUnionMemberId(userVO.getUnionMemberId());
        messageConvert.setServerList(serverConverts);

        ObjectMapper mapper = new ObjectMapper();
        String message = null;
        try {
            message = mapper.writeValueAsString(messageConvert);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        // 发送消息
        rabbitTemplate.convertAndSend(RabbitMQConstants.SITE_DEPLOY_FANOUT_EXCHANGE_NAME, "", message);

        return  R.success().msg("操作成功,后台正在执行部署程序, 请稍后");
        //{"serverList":[{"serverId":"服务器测试修改","route":"path"},{"serverId":"服务器测试2","route":"/usr/data/zxfb2"}],"staticHtmlUrl":"http://10.23.222.147:8888/group1/M00/00/ED/Chfek2IeBFuEIS_mAAAAALsBgr8608.zip"}

    }

}
